﻿using CKS.Core.Framework;
using FreeSql;
using Infrastructure.Extensions;
using Newtonsoft.Json;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ZR.Infrastructure.Helper;
using ZR.Model.Models.ProductionControl;

namespace CKS.PLC.Action.System
{
    public class SaveAlarmAction : PLCAction
    {
        public SaveAlarmAction(DecodeValue value) : base(value)
        {

        }

        public override void Execute(Dictionary<string, object> execParams)
        {
            using (var ObjectCo = base.FreeSql.Ado.MasterPool.Get())
            {
                //db
                var conn = ObjectCo.Value;
                //点位值
                var result = DecodeValue.Value as List<bool>;
                //点位信息
                var postionData = DecodeValue.Position;

                //Debug.WriteLine(JsonConvert.SerializeObject(postionData));

                var plc_id = DecodeValue.SiemensClient.PlcInfo.Id;
                var block_addr = postionData.BlockDb;
                var alarm_addr = postionData.BytePosition;
               
                if (result.Any(o=>o)) //存在True说明有报警
                {
                    List<CksAlarmRecord> insertOrUpdateAlarmRecs = new List<CksAlarmRecord>();

                    //查询当前报警信息
                    var alarmList = conn.Select<CksAlarmRecord>()
                            .Where(o => o.PlcID == plc_id && o.BlockAddr == block_addr && o.AlarmAddr == alarm_addr && o.EndTime == null)
                            .ToList();

                    for (int i = 0; i < result.Count; i++)
                    {
                        //获取当前word 中 当前 bit位的数据
                        var curAlarmInfo = alarmList.Where(o => o.AlarmBitIndex == i).LastOrDefault();
                        //如果数据库中不存在，并且当前bit位的数据为1则新增一条报警记录
                        if (curAlarmInfo == null && result[i])
                        {
                            var alarmRow = new CksAlarmRecord()
                            {
                                PlcID = plc_id,
                                BlockAddr = block_addr,
                                AlarmAddr = Convert.ToInt32(alarm_addr),
                                AlarmBitIndex = i,
                                Value = result[i],
                                StartTime = DateTime.Now
                            };
                            insertOrUpdateAlarmRecs.Add(alarmRow);
                        }
                        else if (curAlarmInfo != null && curAlarmInfo.Value != result[i])
                        {
                            if (curAlarmInfo.Value  && result[i] == false)
                            {
                                curAlarmInfo.Value = result[i];
                                curAlarmInfo.EndTime = DateTime.Now;
                                insertOrUpdateAlarmRecs.Add(curAlarmInfo);
                            }
                            else if (curAlarmInfo.Value == false && result[i])
                            {
                                var alarmRow = new CksAlarmRecord()
                                {
                                    PlcID = plc_id,
                                    BlockAddr = block_addr,
                                    AlarmAddr = Convert.ToInt32(alarm_addr),
                                    AlarmBitIndex = i,
                                    Value = result[i],
                                    StartTime = DateTime.Now
                                };
                                insertOrUpdateAlarmRecs.Add(alarmRow);
                            }
                        }
                    }

                    if (insertOrUpdateAlarmRecs.Count > 0)
                    {
                        var str = JsonConvert.SerializeObject(insertOrUpdateAlarmRecs.Select(o => new { id = o.Id, value = o.Value, index = o.AlarmBitIndex, start = o.StartTime, end = o.EndTime }));
                        Debug.WriteLine(str);
                        int affrowsCut = conn.InsertOrUpdate<CksAlarmRecord>().SetSource(insertOrUpdateAlarmRecs).ExecuteAffrows();
                    }

                }
                else
                {

                    int affrowsCut = 0;

                    var curAlarmInfoList = conn.Select<CksAlarmRecord>()
                            .Where(o => o.PlcID == plc_id && o.BlockAddr == block_addr && o.AlarmAddr == alarm_addr && o.Value)
                            .ToList();

                    curAlarmInfoList.ForEach(item =>
                    {
                        item.Value = false;
                        item.EndTime = DateTime.Now;
                    });

                    if (curAlarmInfoList != null && curAlarmInfoList.Count > 0)
                    {
                        affrowsCut = conn.Update<CksAlarmRecord>().SetSource(curAlarmInfoList).ExecuteAffrows();
                    }
                }
            }

        }
    }
}
